using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

namespace GameSystems
{
    /// <summary>
    /// 社交登录系统 - 处理第三方平台登录集成
    /// </summary>
    public class SocialLoginSystem : MonoBehaviour
    {
        #region Enums

        /// <summary>
        /// 社交平台类型
        /// </summary>
        public enum SocialPlatform
        {
            Facebook,
            Google,
            Twitter,
            Apple,
            WeChat,
            QQ,
            Weibo,
            Steam
        }

        /// <summary>
        /// 登录状态
        /// </summary>
        public enum LoginStatus
        {
            NotLoggedIn,
            LoggingIn,
            LoggedIn,
            Failed
        }

        #endregion

        #region Data Classes

        /// <summary>
        /// 社交用户信息
        /// </summary>
        [Serializable]
        public class SocialUserProfile
        {
            public string platform;
            public string platformUserId;
            public string username;
            public string email;
            public string avatarUrl;
            public string accessToken;
            public string refreshToken;
            public DateTime tokenExpiryTime;
            public Dictionary<string, object> additionalData;

            public SocialUserProfile()
            {
                additionalData = new Dictionary<string, object>();
                tokenExpiryTime = DateTime.Now.AddDays(30);
            }
        }

        /// <summary>
        /// 社交平台配置
        /// </summary>
        [Serializable]
        public class SocialPlatformConfig
        {
            public SocialPlatform platform;
            public string clientId;
            public string clientSecret;
            public string redirectUri;
            public string[] permissions;
            public bool isEnabled = true;
        }

        #endregion

        #region Events

        /// <summary>
        /// 社交登录成功事件
        /// </summary>
        [Serializable] public class SocialLoginSuccessEvent : UnityEvent<SocialUserProfile> { }

        /// <summary>
        /// 社交登录失败事件
        /// </summary>
        [Serializable] public class SocialLoginFailedEvent : UnityEvent<string, string> { }

        /// <summary>
        /// 社交登出事件
        /// </summary>
        [Serializable] public class SocialLogoutEvent : UnityEvent<string> { }

        /// <summary>
        /// 账号绑定成功事件
        /// </summary>
        [Serializable] public class AccountBoundEvent : UnityEvent<string, SocialUserProfile> { }

        /// <summary>
        /// 账号解绑事件
        /// </summary>
        [Serializable] public class AccountUnboundEvent : UnityEvent<string, string> { }

        #endregion

        #region Serialized Fields

        [Header("社交平台配置")]
        [Tooltip("社交平台配置列表")]
        [SerializeField] private List<SocialPlatformConfig> platformConfigs = new List<SocialPlatformConfig>();

        [Header("登录配置")]
        [Tooltip("登录超时时间（秒）")]
        [SerializeField] private float loginTimeout = 30f;

        [Tooltip("是否自动刷新令牌")]
        [SerializeField] private bool autoRefreshToken = true;

        [Tooltip("令牌刷新阈值（天）")]
        [SerializeField] private int tokenRefreshThreshold = 7;

        [Header("UI组件引用")]
        [Tooltip("社交登录按钮列表")]
        [SerializeField] private List<Button> socialLoginButtons = new List<Button>();

        [Tooltip("加载指示器")]
        [SerializeField] private GameObject loadingIndicator;

        [Tooltip("错误信息文本")]
        [SerializeField] private Text errorMessageText;

        [Header("调试选项")]
        [Tooltip("是否启用调试日志")]
        [SerializeField] private bool enableDebugLogs = true;

        [Tooltip("测试模式 - 模拟登录成功")]
        [SerializeField] private bool testMode = false;

        #endregion

        #region Events

        [Header("事件回调")]
        [Tooltip("社交登录成功时触发")]
        public SocialLoginSuccessEvent OnSocialLoginSuccess;

        [Tooltip("社交登录失败时触发")]
        public SocialLoginFailedEvent OnSocialLoginFailed;

        [Tooltip("社交登出时触发")]
        public SocialLogoutEvent OnSocialLogout;

        [Tooltip("账号绑定成功时触发")]
        public AccountBoundEvent OnAccountBound;

        [Tooltip("账号解绑时触发")]
        public AccountUnboundEvent OnAccountUnbound;

        #endregion

        #region Private Fields

        private Dictionary<SocialPlatform, SocialPlatformConfig> configMap = new Dictionary<SocialPlatform, SocialPlatformConfig>();
        private Dictionary<SocialPlatform, LoginStatus> loginStatusMap = new Dictionary<SocialPlatform, LoginStatus>();
        private Dictionary<SocialPlatform, SocialUserProfile> userProfileMap = new Dictionary<SocialPlatform, SocialUserProfile>();
        private Dictionary<SocialPlatform, Coroutine> loginCoroutineMap = new Dictionary<SocialPlatform, Coroutine>();
        private Dictionary<SocialPlatform, string> boundAccountsMap = new Dictionary<SocialPlatform, string>();

        private string currentUsername;
        private Coroutine tokenRefreshCoroutine;

        // 本地存储键
        private const string BoundAccountsKey = "SocialBoundAccounts";
        private const string UserProfileKey = "SocialUserProfile_";

        #endregion

        #region Unity Lifecycle

        /// <summary>
        /// 初始化组件
        /// </summary>
        private void Awake()
        {
            InitializeConfigs();
            InitializeUI();
            LoadBoundAccounts();
            LoadUserProfiles();
        }

        /// <summary>
        /// 启动时的初始化
        /// </summary>
        private void Start()
        {
            if (autoRefreshToken)
            {
                StartTokenRefreshCoroutine();
            }
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        private void OnDestroy()
        {
            CleanupCoroutines();
            SaveUserProfiles();
        }

        /// <summary>
        /// 应用暂停时保存数据
        /// </summary>
        private void OnApplicationPause(bool pauseStatus)
        {
            if (pauseStatus)
            {
                SaveUserProfiles();
            }
        }

        /// <summary>
        /// 应用退出时保存数据
        /// </summary>
        private void OnApplicationQuit()
        {
            SaveUserProfiles();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 执行社交登录
        /// </summary>
        /// <param name="platform">社交平台</param>
        public void LoginWithSocialPlatform(SocialPlatform platform)
        {
            if (!IsPlatformEnabled(platform))
            {
                ShowError($"平台 {platform} 未启用");
                OnSocialLoginFailed?.Invoke(platform.ToString(), "平台未启用");
                return;
            }

            if (IsPlatformLoggedIn(platform))
            {
                LogDebug($"用户已通过 {platform} 平台登录");
                OnSocialLoginSuccess?.Invoke(userProfileMap[platform]);
                return;
            }

            // 取消之前的登录尝试
            CancelLoginAttempt(platform);

            // 开始新的登录尝试
            SetLoginStatus(platform, LoginStatus.LoggingIn);
            ShowLoading(true);

            loginCoroutineMap[platform] = StartCoroutine(SocialLoginCoroutine(platform));
        }

        /// <summary>
        /// 执行社交登出
        /// </summary>
        /// <param name="platform">社交平台</param>
        public void LogoutFromSocialPlatform(SocialPlatform platform)
        {
            if (!IsPlatformLoggedIn(platform))
            {
                LogWarning($"用户未通过 {platform} 平台登录");
                return;
            }

            // 取消登录协程
            if (loginCoroutineMap.ContainsKey(platform) && loginCoroutineMap[platform] != null)
            {
                StopCoroutine(loginCoroutineMap[platform]);
                loginCoroutineMap[platform] = null;
            }

            // 清除用户信息
            if (userProfileMap.ContainsKey(platform))
            {
                userProfileMap.Remove(platform);
                SaveUserProfile(platform);
            }

            SetLoginStatus(platform, LoginStatus.NotLoggedIn);
            OnSocialLogout?.Invoke(platform.ToString());

            LogDebug($"用户已从 {platform} 平台登出");
        }

        /// <summary>
        /// 绑定社交账号到当前用户
        /// </summary>
        /// <param name="platform">社交平台</param>
        /// <param name="username">当前用户名</param>
        public void BindSocialAccount(SocialPlatform platform, string username)
        {
            if (!IsPlatformLoggedIn(platform))
            {
                ShowError("请先登录社交平台");
                return;
            }

            if (IsAccountBound(platform, username))
            {
                ShowError("该社交账号已绑定");
                return;
            }

            currentUsername = username;
            boundAccountsMap[platform] = username;
            SaveBoundAccounts();

            OnAccountBound?.Invoke(username, userProfileMap[platform]);
            LogDebug($"社交账号 {platform} 已绑定到用户 {username}");
        }

        /// <summary>
        /// 解绑社交账号
        /// </summary>
        /// <param name="platform">社交平台</param>
        /// <param name="username">用户名</param>
        public void UnbindSocialAccount(SocialPlatform platform, string username)
        {
            if (!IsAccountBound(platform, username))
            {
                ShowError("该社交账号未绑定");
                return;
            }

            boundAccountsMap.Remove(platform);
            SaveBoundAccounts();

            OnAccountUnbound?.Invoke(username, platform.ToString());
            LogDebug($"社交账号 {platform} 已从用户 {username} 解绑");
        }

        /// <summary>
        /// 获取用户资料
        /// </summary>
        /// <param name="platform">社交平台</param>
        /// <returns>用户资料</returns>
        public SocialUserProfile GetUserProfile(SocialPlatform platform)
        {
            if (userProfileMap.ContainsKey(platform))
            {
                return userProfileMap[platform];
            }
            return null;
        }

        /// <summary>
        /// 获取登录状态
        /// </summary>
        /// <param name="platform">社交平台</param>
        /// <returns>登录状态</returns>
        public LoginStatus GetLoginStatus(SocialPlatform platform)
        {
            if (loginStatusMap.ContainsKey(platform))
            {
                return loginStatusMap[platform];
            }
            return LoginStatus.NotLoggedIn;
        }

        /// <summary>
        /// 检查平台是否已登录
        /// </summary>
        /// <param name="platform">社交平台</param>
        /// <returns>是否已登录</returns>
        public bool IsPlatformLoggedIn(SocialPlatform platform)
        {
            return GetLoginStatus(platform) == LoginStatus.LoggedIn && userProfileMap.ContainsKey(platform);
        }

        /// <summary>
        /// 检查账号是否已绑定
        /// </summary>
        /// <param name="platform">社交平台</param>
        /// <param name="username">用户名</param>
        /// <returns>是否已绑定</returns>
        public bool IsAccountBound(SocialPlatform platform, string username)
        {
            return boundAccountsMap.ContainsKey(platform) && boundAccountsMap[platform] == username;
        }

        /// <summary>
        /// 获取所有绑定的社交账号
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>绑定的平台列表</returns>
        public List<SocialPlatform> GetBoundSocialAccounts(string username)
        {
            List<SocialPlatform> boundPlatforms = new List<SocialPlatform>();

            foreach (var kvp in boundAccountsMap)
            {
                if (kvp.Value == username)
                {
                    boundPlatforms.Add(kvp.Key);
                }
            }

            return boundPlatforms;
        }

        /// <summary>
        /// 从所有平台登出
        /// </summary>
        public void LogoutFromAllPlatforms()
        {
            List<SocialPlatform> loggedInPlatforms = new List<SocialPlatform>();

            foreach (var kvp in loginStatusMap)
            {
                if (kvp.Value == LoginStatus.LoggedIn)
                {
                    loggedInPlatforms.Add(kvp.Key);
                }
            }

            foreach (var platform in loggedInPlatforms)
            {
                LogoutFromSocialPlatform(platform);
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 初始化配置
        /// </summary>
        private void InitializeConfigs()
        {
            configMap.Clear();

            foreach (var config in platformConfigs)
            {
                configMap[config.platform] = config;
                loginStatusMap[config.platform] = LoginStatus.NotLoggedIn;
            }
        }

        /// <summary>
        /// 初始化UI
        /// </summary>
        private void InitializeUI()
        {
            for (int i = 0; i < socialLoginButtons.Count && i < platformConfigs.Count; i++)
            {
                var platform = platformConfigs[i].platform;
                var button = socialLoginButtons[i];

                if (button != null)
                {
                    button.onClick.AddListener(() => LoginWithSocialPlatform(platform));
                    button.interactable = platformConfigs[i].isEnabled;
                }
            }

            ShowLoading(false);
        }

        /// <summary>
        /// 社交登录协程
        /// </summary>
        private IEnumerator SocialLoginCoroutine(SocialPlatform platform)
        {
            LogDebug($"开始 {platform} 平台登录流程");

            // 实际项目中，这里应该调用相应平台的SDK
            if (testMode)
            {
                yield return new WaitForSeconds(2f);

                // 模拟登录成功
                var userProfile = CreateTestUserProfile(platform);
                userProfileMap[platform] = userProfile;
                SetLoginStatus(platform, LoginStatus.LoggedIn);
                SaveUserProfile(platform);

                ShowLoading(false);
                OnSocialLoginSuccess?.Invoke(userProfile);
                LogDebug($"{platform} 平台登录成功");
            }
            else
            {
                // 实际的登录逻辑
                yield return StartCoroutine(ActualSocialLogin(platform));
            }

            loginCoroutineMap[platform] = null;
        }

        /// <summary>
        /// 实际的社交登录逻辑
        /// </summary>
        private IEnumerator ActualSocialLogin(SocialPlatform platform)
        {
            // 这里应该实现实际的社交登录逻辑
            // 例如：调用Facebook SDK、Google Sign-In等

            // 模拟网络请求
            yield return new WaitForSeconds(1f);

            // 根据不同平台实现不同的登录逻辑
            switch (platform)
            {
                case SocialPlatform.Facebook:
                    yield return StartCoroutine(FacebookLogin());
                    break;
                case SocialPlatform.Google:
                    yield return StartCoroutine(GoogleLogin());
                    break;
                case SocialPlatform.Twitter:
                    yield return StartCoroutine(TwitterLogin());
                    break;
                case SocialPlatform.Apple:
                    yield return StartCoroutine(AppleLogin());
                    break;
                case SocialPlatform.WeChat:
                    yield return StartCoroutine(WeChatLogin());
                    break;
                case SocialPlatform.QQ:
                    yield return StartCoroutine(QQLogin());
                    break;
                case SocialPlatform.Weibo:
                    yield return StartCoroutine(WeiboLogin());
                    break;
                case SocialPlatform.Steam:
                    yield return StartCoroutine(SteamLogin());
                    break;
            }
        }

        // 各平台的具体登录实现（示例）
        private IEnumerator FacebookLogin()
        {
            // 实际的Facebook登录逻辑
            yield return new WaitForSeconds(1f);
        }

        private IEnumerator GoogleLogin()
        {
            // 实际的Google登录逻辑
            yield return new WaitForSeconds(1f);
        }

        private IEnumerator TwitterLogin()
        {
            // 实际的Twitter登录逻辑
            yield return new WaitForSeconds(1f);
        }

        private IEnumerator AppleLogin()
        {
            // 实际的Apple登录逻辑
            yield return new WaitForSeconds(1f);
        }

        private IEnumerator WeChatLogin()
        {
            // 实际的微信登录逻辑
            yield return new WaitForSeconds(1f);
        }

        private IEnumerator QQLogin()
        {
            // 实际的QQ登录逻辑
            yield return new WaitForSeconds(1f);
        }

        private IEnumerator WeiboLogin()
        {
            // 实际的微博登录逻辑
            yield return new WaitForSeconds(1f);
        }

        private IEnumerator SteamLogin()
        {
            // 实际的Steam登录逻辑
            yield return new WaitForSeconds(1f);
        }

        /// <summary>
        /// 创建测试用户资料
        /// </summary>
        private SocialUserProfile CreateTestUserProfile(SocialPlatform platform)
        {
            var userProfile = new SocialUserProfile
            {
                platform = platform.ToString(),
                platformUserId = $"test_{platform}_user_123",
                username = $"Test{platform}User",
                email = $"test_{platform.ToLower()}@example.com",
                avatarUrl = $"https://example.com/avatar_{platform.ToLower()}.png",
                accessToken = $"test_access_token_{platform}",
                refreshToken = $"test_refresh_token_{platform}"
            };

            return userProfile;
        }

        /// <summary>
        /// 设置登录状态
        /// </summary>
        private void SetLoginStatus(SocialPlatform platform, LoginStatus status)
        {
            loginStatusMap[platform] = status;
        }

        /// <summary>
        /// 取消登录尝试
        /// </summary>
        private void CancelLoginAttempt(SocialPlatform platform)
        {
            if (loginCoroutineMap.ContainsKey(platform) && loginCoroutineMap[platform] != null)
            {
                StopCoroutine(loginCoroutineMap[platform]);
                loginCoroutineMap[platform] = null;
            }
        }

        /// <summary>
        /// 检查平台是否启用
        /// </summary>
        private bool IsPlatformEnabled(SocialPlatform platform)
        {
            return configMap.ContainsKey(platform) && configMap[platform].isEnabled;
        }

        /// <summary>
        /// 显示加载指示器
        /// </summary>
        private void ShowLoading(bool show)
        {
            if (loadingIndicator != null)
                loadingIndicator.SetActive(show);
        }

        /// <summary>
        /// 显示错误信息
        /// </summary>
        private void ShowError(string message)
        {
            LogError(message);
            if (errorMessageText != null)
                errorMessageText.text = message;
        }

        /// <summary>
        /// 启动令牌刷新协程
        /// </summary>
        private void StartTokenRefreshCoroutine()
        {
            if (tokenRefreshCoroutine != null)
            {
                StopCoroutine(tokenRefreshCoroutine);
            }

            tokenRefreshCoroutine = StartCoroutine(TokenRefreshCoroutine());
        }

        /// <summary>
        /// 令牌刷新协程
        /// </summary>
        private IEnumerator TokenRefreshCoroutine()
        {
            while (true)
            {
                yield return new WaitForSeconds(3600f); // 每小时检查一次

                foreach (var kvp in userProfileMap)
                {
                    var platform = kvp.Key;
                    var userProfile = kvp.Value;

                    if (userProfile != null && ShouldRefreshToken(userProfile))
                    {
                        yield return StartCoroutine(RefreshToken(platform, userProfile));
                    }
                }
            }
        }

        /// <summary>
        /// 检查是否应该刷新令牌
        /// </summary>
        private bool ShouldRefreshToken(SocialUserProfile userProfile)
        {
            var daysUntilExpiry = (userProfile.tokenExpiryTime - DateTime.Now).Days;
            return daysUntilExpiry <= tokenRefreshThreshold;
        }

        /// <summary>
        /// 刷新令牌协程
        /// </summary>
        private IEnumerator RefreshToken(SocialPlatform platform, SocialUserProfile userProfile)
        {
            LogDebug($"刷新 {platform} 平台令牌");

            // 实际项目中，这里应该调用相应平台的令牌刷新API
            yield return new WaitForSeconds(1f);

            // 模拟令牌刷新成功
            userProfile.tokenExpiryTime = DateTime.Now.AddDays(30);
            SaveUserProfile(platform);

            LogDebug($"{platform} 平台令牌刷新成功");
        }

        /// <summary>
        /// 加载绑定的社交账号
        /// </summary>
        private void LoadBoundAccounts()
        {
            if (PlayerPrefs.HasKey(BoundAccountsKey))
            {
                try
                {
                    string jsonData = PlayerPrefs.GetString(BoundAccountsKey);
                    var boundData = JsonUtility.FromJson<BoundAccountsData>(jsonData);

                    if (boundData != null && boundData.accounts != null)
                    {
                        boundAccountsMap.Clear();
                        foreach (var account in boundData.accounts)
                        {
                            if (Enum.TryParse<SocialPlatform>(account.platform, out var platform))
                            {
                                boundAccountsMap[platform] = account.username;
                            }
                        }
                        LogDebug($"已加载 {boundAccountsMap.Count} 个绑定社交账号");
                    }
                }
                catch (Exception e)
                {
                    LogError($"加载绑定社交账号失败: {e.Message}");
                }
            }
        }

        /// <summary>
        /// 保存绑定的社交账号
        /// </summary>
        private void SaveBoundAccounts()
        {
            try
            {
                var boundData = new BoundAccountsData
                {
                    accounts = new List<BoundAccountInfo>()
                };

                foreach (var kvp in boundAccountsMap)
                {
                    boundData.accounts.Add(new BoundAccountInfo
                    {
                        platform = kvp.Key.ToString(),
                        username = kvp.Value
                    });
                }

                string jsonData = JsonUtility.ToJson(boundData, true);
                PlayerPrefs.SetString(BoundAccountsKey, jsonData);
                PlayerPrefs.Save();

                LogDebug($"已保存 {boundAccountsMap.Count} 个绑定社交账号");
            }
            catch (Exception e)
            {
                LogError($"保存绑定社交账号失败: {e.Message}");
            }
        }

        /// <summary>
        /// 加载用户资料
        /// </summary>
        private void LoadUserProfiles()
        {
            foreach (var config in platformConfigs)
            {
                var platform = config.platform;
                string key = UserProfileKey + platform.ToString();

                if (PlayerPrefs.HasKey(key))
                {
                    try
                    {
                        string jsonData = PlayerPrefs.GetString(key);
                        var userProfile = JsonUtility.FromJson<SocialUserProfile>(jsonData);

                        if (userProfile != null)
                        {
                            userProfileMap[platform] = userProfile;
                            SetLoginStatus(platform, LoginStatus.LoggedIn);
                        }
                    }
                    catch (Exception e)
                    {
                        LogError($"加载 {platform} 用户资料失败: {e.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 保存用户资料
        /// </summary>
        private void SaveUserProfiles()
        {
            foreach (var kvp in userProfileMap)
            {
                SaveUserProfile(kvp.Key);
            }
        }

        /// <summary>
        /// 保存单个平台的用户资料
        /// </summary>
        private void SaveUserProfile(SocialPlatform platform)
        {
            if (!userProfileMap.ContainsKey(platform))
                return;

            try
            {
                string key = UserProfileKey + platform.ToString();
                string jsonData = JsonUtility.ToJson(userProfileMap[platform], true);
                PlayerPrefs.SetString(key, jsonData);
            }
            catch (Exception e)
            {
                LogError($"保存 {platform} 用户资料失败: {e.Message}");
            }
        }

        /// <summary>
        /// 清理协程
        /// </summary>
        private void CleanupCoroutines()
        {
            foreach (var kvp in loginCoroutineMap)
            {
                if (kvp.Value != null)
                {
                    StopCoroutine(kvp.Value);
                }
            }
            loginCoroutineMap.Clear();

            if (tokenRefreshCoroutine != null)
            {
                StopCoroutine(tokenRefreshCoroutine);
                tokenRefreshCoroutine = null;
            }
        }

        #endregion

        #region Debug Methods

        /// <summary>
        /// 调试日志
        /// </summary>
        private void LogDebug(string message)
        {
            if (enableDebugLogs)
                Debug.Log($"[SocialLoginSystem] {message}");
        }

        /// <summary>
        /// 警告日志
        /// </summary>
        private void LogWarning(string message)
        {
            if (enableDebugLogs)
                Debug.LogWarning($"[SocialLoginSystem] {message}");
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        private void LogError(string message)
        {
            if (enableDebugLogs)
                Debug.LogError($"[SocialLoginSystem] {message}");
        }

        #endregion

        #region Data Structures

        /// <summary>
        /// 绑定账号信息
        /// </summary>
        [Serializable]
        private class BoundAccountInfo
        {
            public string platform;
            public string username;
        }

        /// <summary>
        /// 绑定账号数据
        /// </summary>
        [Serializable]
        private class BoundAccountsData
        {
            public List<BoundAccountInfo> accounts;
            public DateTime lastUpdated;
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// 是否启用测试模式
        /// </summary>
        public bool TestMode
        {
            get => testMode;
            set => testMode = value;
        }

        /// <summary>
        /// 当前用户名
        /// </summary>
        public string CurrentUsername => currentUsername;

        #endregion
    }
}
